import { useMemo, useState } from 'react'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import dayjs from 'dayjs'

import { CycleAPI } from '../app/api'
import type { ApiCycleDayLog, ApiCyclePrediction } from '../app/types'
import PageHeader from '../components/PageHeader'

const FLOW_OPTIONS: Array<{ key: 'light' | 'medium' | 'heavy'; label: string; className: string }> = [
  { key: 'light', label: '少量', className: 'bg-gradient-to-r from-rose-50 to-rose-100 text-rose-600 ring-1 ring-rose-200' },
  { key: 'medium', label: '中等', className: 'bg-gradient-to-r from-rose-200 to-rose-100 text-rose-700 ring-1 ring-rose-300' },
  { key: 'heavy', label: '较多', className: 'bg-gradient-to-r from-rose-400 to-rose-500 text-white ring-1 ring-rose-400' },
]

const FLOW_BADGES: Record<string, string> = {
  none: 'bg-slate-100 text-slate-500 ring-1 ring-slate-200',
  light: 'bg-gradient-to-br from-rose-50 via-rose-100 to-rose-50 text-rose-600 ring-1 ring-rose-200',
  medium: 'bg-gradient-to-br from-rose-200 via-rose-300 to-rose-200 text-rose-700 ring-1 ring-rose-300',
  heavy: 'bg-gradient-to-br from-rose-400 via-rose-500 to-rose-400 text-white ring-1 ring-rose-400',
}

const PHASE_LABELS: Record<string, string> = {
  menstruation: '月经期',
  follicular: '卵泡期',
  fertile: '排卵期',
  luteal: '黄体期',
}

const getPhaseLabel = (prediction: ApiCyclePrediction) =>
  prediction.phase_label ?? PHASE_LABELS[prediction.phase] ?? prediction.phase

const CyclePage = () => {
  if (typeof document !== 'undefined') document.title = '生理周期 · Love Notes'
  const [currentMonth, setCurrentMonth] = useState(() => dayjs())
  const [activeFlow, setActiveFlow] = useState<'light' | 'medium' | 'heavy'>('light')

  const queryClient = useQueryClient()

  const { data: predictions = [], isLoading: predictionsLoading } = useQuery({
    queryKey: ['cycle', 'predictions'],
    queryFn: CycleAPI.listPredictions,
  })

  const monthLogsQuery = useQuery({
    queryKey: ['cycle', 'day-logs', currentMonth.year(), currentMonth.month() + 1],
    queryFn: () => CycleAPI.listDayLogs({ year: currentMonth.year(), month: currentMonth.month() + 1 }),
  })

  const dayLogsByDate = useMemo(() => {
    const entries = monthLogsQuery.data ?? []
    return Object.fromEntries(entries.map((log) => [log.date, log])) as Record<string, ApiCycleDayLog>
  }, [monthLogsQuery.data])

  const daysInMonth = useMemo(() => {
    const start = currentMonth.startOf('month')
    const end = currentMonth.endOf('month')
    const days: string[] = []
    let d = start
    while (d.isBefore(end) || d.isSame(end, 'day')) {
      days.push(d.format('YYYY-MM-DD'))
      d = d.add(1, 'day')
    }
    return days
  }, [currentMonth])

  const firstWeekday = useMemo(() => {
    const day = currentMonth.startOf('month').day()
    return (day + 6) % 7 // convert Sunday=0 to Monday-indexed
  }, [currentMonth])

  const trailingPlaceholders = useMemo(() => {
    const totalCells = firstWeekday + daysInMonth.length
    const remainder = totalCells % 7
    return remainder === 0 ? 0 : 7 - remainder
  }, [firstWeekday, daysInMonth.length])

  const handleDayToggle = async (date: string) => {
    const existing = dayLogsByDate[date]
    if (existing) {
      await CycleAPI.deleteDayLog(date)
    } else {
      await CycleAPI.upsertDayLog({ date, flow_level: activeFlow })
    }
    await Promise.all([
      queryClient.invalidateQueries({ queryKey: ['cycle', 'day-logs', currentMonth.year(), currentMonth.month() + 1] }),
      queryClient.invalidateQueries({ queryKey: ['cycle', 'predictions'] }),
    ])
  }

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Cycle"
        title="生理期关怀"
        description="用日历记录流量，结合历史平均预测下一阶段，提前安排休息与惊喜。"
      />

      {/* Monthly day-by-day grid */}
      <section className="rounded-3xl border border-slate-100 bg-white/95 p-6 shadow-card">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div className="flex items-center gap-2 text-sm">
            <button className="btn-ghost rounded-full px-3 py-1" onClick={() => setCurrentMonth((m) => m.subtract(1, 'month'))}>上个月</button>
            <span className="text-slate-600">{currentMonth.format('YYYY 年 M 月')}</span>
            <button className="btn-ghost rounded-full px-3 py-1" onClick={() => setCurrentMonth((m) => m.add(1, 'month'))}>下个月</button>
          </div>
          <div className="flex flex-wrap items-center gap-2 text-xs text-slate-500">
            <span className="text-slate-400">默认流量：</span>
            {FLOW_OPTIONS.map((option) => (
              <button
                key={option.key}
                className={`rounded-full px-3 py-1 font-semibold transition ${option.className} ${activeFlow === option.key ? 'scale-[1.03] shadow-sm' : 'opacity-70 hover:opacity-100'}`}
                onClick={() => setActiveFlow(option.key)}
              >
                {option.label}
              </button>
            ))}
          </div>
        </div>
        <div className="mt-4 grid grid-cols-7 gap-2 text-xs">
          {['一','二','三','四','五','六','日'].map((w) => (
            <div key={w} className="px-2 py-1 text-center font-semibold text-slate-400">{w}</div>
          ))}
          {Array.from({ length: firstWeekday }).map((_, idx) => (
            <div key={`lead-${idx}`} className="rounded-3xl border border-dashed border-slate-100" aria-hidden />
          ))}
          {daysInMonth.map((d) => {
            const log = dayLogsByDate[d]
            const dayNum = dayjs(d).date()
            const isToday = dayjs().isSame(d, 'day')
            const isFuture = dayjs(d).isAfter(dayjs(), 'day')
            const level = log?.flow_level || 'none'
            const tones = FLOW_BADGES[level] ?? FLOW_BADGES.none
            return (
              <button
                key={d}
                className={`group relative grid aspect-square place-items-center rounded-3xl px-2 text-sm font-semibold transition ${
                  isFuture ? 'cursor-not-allowed opacity-50' : 'hover:-translate-y-0.5'
                } ${tones} ${isToday ? 'ring-2 ring-offset-2 ring-rose-200' : ''}`}
                onClick={() => !isFuture && handleDayToggle(d)}
                disabled={isFuture}
              >
                <span>{dayNum}</span>
                {!log && isToday ? (
                  <span className="absolute inset-0 rounded-3xl border border-dashed border-rose-200" aria-hidden />
                ) : null}
              </button>
            )
          })}
          {Array.from({ length: trailingPlaceholders }).map((_, idx) => (
            <div key={`trail-${idx}`} className="rounded-3xl border border-dashed border-slate-100" aria-hidden />
          ))}
        </div>
        <p className="mt-3 text-xs text-slate-400">点击日期可快速记录/删除，当日默认使用选择的流量强度。</p>
      </section>

      <section className="rounded-3xl border border-slate-100 bg-white/95 p-6 shadow-card">
        <h2 className="text-base font-semibold text-slate-900">未来周期预测</h2>
        <p className="mt-1 text-sm text-slate-500">基于历史数据推断的下一个阶段，帮你提前安排休息与惊喜。</p>
        <div className="mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {predictionsLoading ? (
            <p className="text-sm text-slate-400">预测加载中...</p>
          ) : predictions.length === 0 ? (
            <div className="rounded-2xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-center text-sm text-slate-500">
              暂无预测数据，可先补充生理期记录。
            </div>
          ) : (
            predictions.slice(0, 3).map((item) => <PredictionCard key={item.id} prediction={item} />)
          )}
        </div>
      </section>

    </div>
  )
}
const PHASE_ACCENTS: Record<string, string> = {
  menstruation: 'from-rose-400 to-rose-500',
  follicular: 'from-sky-400 to-cyan-400',
  fertile: 'from-emerald-400 to-lime-400',
  luteal: 'from-violet-500 to-lavender-500',
}

const PredictionCard = ({ prediction }: { prediction: ApiCyclePrediction }) => {
  const label = getPhaseLabel(prediction)
  const confidence = Math.round(prediction.confidence * 100)
  const accent = PHASE_ACCENTS[prediction.phase] ?? 'from-slate-400/80 via-slate-300/70 to-slate-500/60'
  const today = dayjs()
  const start = dayjs(prediction.start_date)
  const end = dayjs(prediction.end_date)
  let countdown = ''
  if (start.isAfter(today, 'day')) {
    const days = start.diff(today, 'day')
    countdown = days === 0 ? '今天起' : `还有 ${days} 天`
  } else if (end.isAfter(today, 'day')) {
    countdown = '进行中'
  } else {
    countdown = '已结束'
  }

  return (
    <article className="rounded-3xl border border-slate-100 bg-white/95 p-5 shadow-soft">
      <div className={`h-1.5 w-full rounded-full bg-gradient-to-r ${accent} opacity-80`} />
      <div className="mt-3 flex items-center justify-between gap-4 text-slate-700">
        <span className="rounded-full border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-semibold tracking-wide">
          {label}
        </span>
        <span className="text-[11px] font-medium text-slate-500">{countdown}</span>
      </div>
      <p className="mt-3 text-lg font-semibold text-slate-900">
        {start.format('MM-DD')} ~ {end.format('MM-DD')}
      </p>
      <div className="mt-3 h-1.5 w-full overflow-hidden rounded-full bg-slate-100">
        <div
          className="h-full rounded-full bg-slate-500"
          style={{ width: `${Math.min(Math.max(confidence, 8), 100)}%` }}
        />
      </div>
      <p className="mt-2 text-xs text-slate-500">置信度 {confidence}%</p>
    </article>
  )
}

export default CyclePage
